package org.jim.server.command.handler;

import java.util.List;
import java.util.Objects;

import org.jim.core.ImChannelContext;
import org.jim.core.ImPacket;
import org.jim.core.ImStatus;
import org.jim.core.cache.redis.RedisCacheManager;
import org.jim.core.config.ImConfig;
import org.jim.core.exception.ImException;
import org.jim.core.message.MessageHelper;
import org.jim.core.packets.ChatBody;
import org.jim.core.packets.ChatType;
import org.jim.core.packets.Command;
import org.jim.core.packets.Group;
import org.jim.core.packets.RespBody;
import org.jim.core.packets.User;
import org.jim.core.packets.UserStatusType;
import org.jim.server.ImServerChannelContext;
import org.jim.server.JimServerAPI;
import org.jim.server.command.AbstractCmdHandler;
import org.jim.server.command.handler.extend.utils.SystemNotify;
import org.jim.server.command.handler.extend.utils.SystemNotify.Operation;
import org.jim.server.config.ImServerConfig;
import org.jim.server.protocol.ProtocolManager;
import org.jim.server.protocol.ProtocolManager.Converter;
import org.jim.server.queue.MsgQueueRunnable;
import org.jim.server.util.ChatKit;
import org.jim.server.util.Common;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * 版本: [1.0]
 * 功能说明: 聊天请求cmd消息命令处理器
 * @author : WChao 创建时间: 2017年9月22日 下午2:58:59
 */
public class ChatReqHandler extends AbstractCmdHandler {
	private static Logger logger = LoggerFactory.getLogger(ChatReqHandler.class);
	@Override
	public ImPacket handler(ImPacket packet, ImChannelContext channelContext) throws ImException {
		ImServerChannelContext imServerChannelContext = (ImServerChannelContext)channelContext;
		if (packet.getBody() == null) {
			throw new ImException("body is null");
		}
		ChatBody chatBody = ChatKit.toChatBody(packet.getBody(), channelContext);
		//日志信息
		logger.info(JSON.toJSONString(chatBody));
		//系统赋予时间
		chatBody.setCreateTime(System.currentTimeMillis());
		//TODO 将来额外增加 增加from姓名|to姓名
		ImServerConfig imServerConfig = ImConfig.Global.get();
		MessageHelper messageHelper = imServerConfig.getMessageHelper();
		User fromUser = messageHelper.getUserByType(chatBody.getFrom(),UserStatusType.ALL.getNumber());
		//TODO 将来额外增加 extend
		if(ChatType.CHAT_TYPE_PRIVATE.getNumber() == chatBody.getChatType()){
			
			User toUser = messageHelper.getUserByType(chatBody.getTo(),UserStatusType.ALL.getNumber());
			if(toUser == null) {
				RespBody respBody  = new RespBody(Command.SYSTEM_RESP, ImStatus.C2002).setMsg("聊天用户不存在");
				JSONObject js = new JSONObject();
				js.put("userId", chatBody.getTo());
				SystemNotify.notifyUser(fromUser.getUserId(), fromUser.getNick(),
							"聊天用户不存在",Operation.oper_chat_list_remove,js);
				return ProtocolManager.Converter.respPacket(respBody, channelContext);
			}
			JSONObject  js = new JSONObject();
			js.put("fromUserName", fromUser.getNick());
			js.put("fromUserAvatar", fromUser.getAvatar());
			js.put("toUserName", toUser.getNick());
			js.put("toUserAvatar", toUser.getAvatar());
			chatBody.setExtras(js);
			
			
		}else if(ChatType.CHAT_TYPE_PUBLIC.getNumber() == chatBody.getChatType()){
			String groupId = chatBody.getGroupId();
			Group group = RedisCacheManager.getCache(GROUP).get(groupId+Common.SUFFIX+INFO , Group.class);
			JSONObject exjs = new JSONObject();
			exjs.put("groupId", groupId);
			if(Objects.isNull(group)) {
				
				SystemNotify.notifyUser(fromUser.getUserId(), fromUser.getNick(),
						"聊天群组不存在",Operation.oper_chat_list_remove,exjs);
				RespBody respBody  = new RespBody(Command.COMMAND_CHAT_RESP, ImStatus.C2002).setMsg("群组不存在");
				return ProtocolManager.Converter.respPacket(respBody, channelContext);
			}
			List<String> groups = messageHelper.getGroups(fromUser.getUserId());
			if(groups == null || !groups.contains(groupId)) {
				SystemNotify.notifyUser(fromUser.getUserId(), fromUser.getNick(),
						"你已被移除该群",Operation.oper_chat_list_remove,exjs);
				RespBody respBody  = new RespBody(Command.COMMAND_CHAT_RESP, ImStatus.C2002).setMsg("你已被移除该群");
				return ProtocolManager.Converter.respPacket(respBody, channelContext);
			}
			JSONObject  js = new JSONObject();
			js.put("fromUserName", fromUser.getNick());
			js.put("fromUserAvatar", fromUser.getAvatar());
			js.put("groupName", group.getName());
			js.put("groupAvatar", group.getAvatar());
			chatBody.setExtras(js);
		}
		
		
		
		packet.setBody(chatBody.toByte());
		//聊天数据格式不正确
		if(chatBody == null || ChatType.forNumber(chatBody.getChatType()) == null){
			ImPacket respChatPacket = ProtocolManager.Packet.dataInCorrect(channelContext);
			return respChatPacket;
		}
		//异步调用业务处理消息接口
		MsgQueueRunnable msgQueueRunnable = getMsgQueueRunnable(imServerChannelContext);
		msgQueueRunnable.addMsg(chatBody);
		msgQueueRunnable.executor.execute(msgQueueRunnable);
		ImPacket chatPacket = new ImPacket(Command.COMMAND_CHAT_RESP,new RespBody(Command.COMMAND_CHAT_RESP,chatBody).toByte());
		//设置同步序列号;
		chatPacket.setSynSeq(packet.getSynSeq());
		//ImServerConfig imServerConfig = ImConfig.Global.get();
		boolean isStore = ImServerConfig.ON.equals(imServerConfig.getIsStore());
		//TODO 只要是私聊，我举得自身需要反馈发送了什么。不知道理解的对不对，我觉得这个还不够。后续还需要调优
		//私聊
		if(ChatType.CHAT_TYPE_PRIVATE.getNumber() == chatBody.getChatType()){
			
			String toId = chatBody.getTo();
			if(ChatKit.isOnline(toId, isStore)){
				JimServerAPI.sendToUser(toId, chatPacket);
				//发送成功响应包 
				//ImPacket resp = ProtocolManager.Packet.success(channelContext);
				RespBody resp = new RespBody(Command.COMMAND_CHAT_RESP, ImStatus.C10000);
				resp.setData(chatBody);
				ImPacket respPacket = Converter.respPacket(resp, channelContext);
				return respPacket;
				
				
			}else{
				//用户不在线响应包
				//return ProtocolManager.Packet.offline(channelContext);
				//ImPacket resp = ProtocolManager.Packet.offline(channelContext);
				//return resp;
				//resp.setBody(chatBody.toByte());
				RespBody resp = new RespBody(Command.COMMAND_CHAT_RESP,ImStatus.C10001);
				resp.setData(chatBody);
				ImPacket respPacket = Converter.respPacket(resp, channelContext);
				return respPacket;
				
			}
		//群聊
		}else if(ChatType.CHAT_TYPE_PUBLIC.getNumber() == chatBody.getChatType()){
			String groupId = chatBody.getGroupId();
			
			JimServerAPI.sendToGroup(groupId, chatPacket);
			
			//发送成功响应包
			return ProtocolManager.Packet.success(channelContext);
		}
		
		
		return null;
	}
	
	//TODO 暂停
	private void updChatRecord(MessageHelper messageHelper,String from,String to) {
		//extend业务 ，维护聊天记录.无论跟谁聊，无论被动还是主动聊，聊天最近的时间的排位在第一位；
		//存放  id   type（1:个人  2：组） createTime 时间戳
		
		//messageHelper.writeMessage(ImConst.USER, from+":"+ImConst.CHAT, chatBody);
		//messageHelper.writeMessage(ImConst.USER, from+":"+ImConst.CHAT, chatBody);		
	}
	
	@Override
	public Command command() {
		return Command.COMMAND_CHAT_REQ;
	}

	/**
	 * 获取聊天业务处理异步消息队列
	 * @param imServerChannelContext IM通道上下文
	 * @return
	 */
	private MsgQueueRunnable getMsgQueueRunnable(ImServerChannelContext imServerChannelContext){
		MsgQueueRunnable msgQueueRunnable = (MsgQueueRunnable)imServerChannelContext.getMsgQue();
		if(Objects.nonNull(msgQueueRunnable.getProtocolCmdProcessor())){
			return msgQueueRunnable;
		}
		synchronized (MsgQueueRunnable.class){
			msgQueueRunnable.setProtocolCmdProcessor(this.getSingleProcessor());
		}
		return msgQueueRunnable;
	}

}
